__author__ = 'Frank'
__version__ = '1.2.9'

import os, os.path

from fabric.api import lcd, local, cd, hosts, task
from fabric.operations import run, put
from fabric.contrib.project import rsync_project
from gitric.api import git_seed, git_reset, allow_dirty, force_push
from fabric.contrib.files import exists


class Deploy:
    def __init__(self, deployPath, projectName):
        self.deployPath = deployPath
        self.projectName = projectName
        self.autoCreateDirs = []

    def upload(self):
        run('mkdir -p %s' % self.deployPath)

        # upload
        git_seed(self.deployPath, None)
        git_reset(self.deployPath, None)

        return self

    def config(self, fileMapping):
        with cd(self.deployPath):
            for fromPath, toPath in fileMapping.iteritems():
                run('mkdir -p %s' % os.path.dirname(os.path.join(self.deployPath, toPath)))  #create parent
                run('cp -f %s %s' % (fromPath, toPath))

    def ensureDirs(self, dirs):
        self.autoCreateDirs = dirs

        for confirmDir in dirs:
            run('mkdir -p %s' % os.path.join(self.deployPath, confirmDir))

    def mergeHtaccessAuto(self):
        if (os.path.isfile('.server.htaccess') and os.path.isfile('.htaccess')):
            with cd(self.deployPath):
                run('cat .server.htaccess .htaccess > .htaccess.tmp')
                run('mv .htaccess.tmp .htaccess')

    def dependencyAuto(self):
        ''' auto task '''

        # composer
        if (os.path.isfile('composer.json')):
            vendorPath = os.path.join(self.deployPath, 'vendor')
            with cd(vendorPath):
                if(exists(vendorPath)):
                    # fix vendor permission bug
                    run("for file in `find . -name '*.git' -print 2>/dev/null`;do cd %s/$file/../;git reset --hard;done" % vendorPath)

            with cd(self.deployPath):
                run('composer update --prefer-source')

        # bower
        if (os.path.isfile('bower.json')):
            with cd(self.deployPath):
                run('bower update  --allow-root')
            local('bower update  --allow-root')  #local

        topDirs = os.walk('.').next()[1]
        for dir in topDirs:
            if (os.path.isfile(os.path.join(dir, 'bower.json'))):
                with cd(os.path.join(self.deployPath, dir)):
                    run('bower update  --allow-root')
                with lcd(dir):
                    local('bower update  --allow-root')  #local


    def clearCacheAuto(self):
        ''' auto task '''

        topDirs = os.walk('.').next()[1]
        for dir in topDirs:
            # view cache
            cachePath = os.path.join(self.deployPath, dir, 'app/cache')
            if (exists(cachePath)):
                run('rm -f %s' % os.path.join(cachePath, '*'))


    def buildHtml(self, siteDirs):
        ''' build target should be ./dist/ '''
        for dir in siteDirs:
            with lcd(dir):
                local('npm install')
                local('gulp build')

        rsync_project(remote_dir=self.deployPath, local_dir='./dist/*')

    def resetPerms(self, ownUser, strictMode=False):
        with cd(self.deployPath):
            run('chown -R %s ./' % ownUser)
            if (strictMode):
                run('chmod -R 555 ./')
            else:
                run('chmod -R 755 ./')

            if (strictMode and hasattr(self, 'autoCreateDirs')):
                for dir in self.autoCreateDirs:
                    with cd(dir):
                        run('chmod -R 755 ./')  #writable


    def genApacheConf(self, domain, domainAlias='not.defined'):
        apacheConfTpl = """
            <VirtualHost *:80>
                    ServerName %(domain)s
                    ServerAlias %(domainAlias)s
                    ServerAdmin guoxiao@cdreami.com
                    DocumentRoot "%(remoteDir)s"
                    ErrorLog "/var/log/apache2/%(project)s_errors.log"
                    CustomLog "/var/log/apache2/%(project)s_accesses.log" common
                    <Directory />
                            Allow from all
                    </Directory>
            </VirtualHost>
            """
        apacheConfContent = apacheConfTpl % {'domain': domain, 'domainAlias': domainAlias, 'project': self.projectName,
                                             'remoteDir': self.deployPath}

        tempConfFile = self.projectName + '.conf'
        with open(tempConfFile, 'w') as f:
            f.write(apacheConfContent)

        #sync
        put(tempConfFile, '/etc/apache2/sites-enabled/')
        os.remove(tempConfFile)

        #reload apache
        run('service apache2 reload')



